package Leo.serviceClient.service.impl;

import Leo.serviceClient.entity.User;
import Leo.serviceClient.feign.ProviderClient;
import Leo.serviceClient.service.HystrixService;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheKey;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheRemove;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.Future;

@Service
@DefaultProperties(groupKey = "hystrixDemoCommand")
public class HystrixServiceImpl implements HystrixService {

    //    @CacheResult //启动Hystrix的缓存
//    @HystrixCommand(fallbackMethod = "getUserFallBack")

    @Autowired
    ProviderClient providerClient;
    @CacheResult//启动Hystrix的缓存，缓存的key名字为queryuserKey
    @HystrixCommand(fallbackMethod = "getUserFallBack",commandKey = "queryUserKey")
    public User getUserFromSP(String userId) {
        System.out.println("调用Hystrix向SP请求数据");
        User user = providerClient.getUser(userId);
        return user;
    }
    @CacheRemove(commandKey = "queryUserKey")//表示触发此方法时，删除queryUserKey的缓存
    @HystrixCommand
    public User updateUser(User user){
        return user;
    }

    @HystrixCommand(fallbackMethod = "getUserDefaultFallBack"
            , commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "200")}
            , threadPoolProperties = {@HystrixProperty(name = "coreSize", value = "10"),
            @HystrixProperty(name = "maxQueueSize", value = "101"),
            @HystrixProperty(name = "keepAliveTimeMinutes", value = "2"),
            @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"),
            @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "12"),
            @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "1440")})
    public Map<String,User> getUsersFromSP(@CacheKey String userId) {
        Map<String, User> user = providerClient.getUsers(userId);
        Set<Map.Entry<String, User>> entries = user.entrySet();
        for (Map.Entry<String, User> entry : entries) {
            System.out.println(entry.getValue().getUserName());
        }
        return user;
    }

    /**
     * 虚拟查询user，最后还是汇入给getUsers
     * @param userId
     * @return
     */
    @HystrixCollapser(batchMethod = "getUsers",collapserProperties = {
            @HystrixProperty( name = "timerDelayInMilliseconds",value = "20")
    })
    public Future<User> collapseGetUser(String userId) {
        System.out.println("单个方法,userID 参数为：" + userId);
        return null;
    }

    @HystrixCommand(fallbackMethod = "collaspeFallback")
    public List<User> getUsers(@CacheKey List<String> userIds) {
        StringBuilder sb = new StringBuilder();
        System.out.println("启动collapse，一起查询");
        for (String userId : userIds) {
            sb.append(userId).append(",");
        }
        Map<String, User> user = providerClient.getUsers(sb.toString());
        Set<Map.Entry<String, User>> entries = user.entrySet();
        ArrayList<User> list = new ArrayList<User>();
        for (Map.Entry<String, User> entry : entries) {
            System.out.println(entry.getValue().getUserName());
            list.add(entry.getValue());
        }
        return list;
    }


    User getUserFallBack(String userId) {
        User user = new User();
        user.setUserName("斑纹龙天道");
        user.setUserId(userId);
        return user;
    }

    Map<String,User> getUserDefaultFallBack(String userId) {
        User user = new User();
        user.setUserName("胖球");
        user.setUserId(userId);
        HashMap<String, User> map = new HashMap<String, User>();
        map.put(userId,user);
        return map;
    }

    List<User> collaspeFallback(List<String> userId) {
        User user = new User();
        user.setUserName("豆豆");
        user.setUserId("4534");
        List< User> list = new ArrayList<User>();
        list.add(user);
        return list;
    }
}
